﻿using HAF.LogUtility;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace XmlUtility
{
    public class XmlAssistantor
    {
        /// <summary>
        /// 读取发布工单内容
        /// </summary>
        /// <param name="xmlPath"></param>
        /// <returns></returns>
        public string ReadPubXml(string xmlPath)
        {
            try
            {
                if (File.Exists(xmlPath))
                {
                    XDocument rootNode = XDocument.Load(xmlPath);
                    XElement rootElement = rootNode.Root;
                    return rootNode.ToString();
                }
                else
                    return "";
            }
            catch (Exception)
            {
                return "";
            }
        }

        public string ReadXmlContent(string xmlPath)
        {
            StringBuilder sbContent = new StringBuilder();
            try
            {
                using (FileStream fs = new FileStream(xmlPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    byte[] filebytes = new byte[fs.Length];
                    fs.Read(filebytes, 0, Convert.ToInt32(fs.Length));
                    string xmlContent = System.Text.Encoding.UTF8.GetString(filebytes);
                    //WriteDebugMessageEx(_outParams.CorrelateID, string.Format("回单文件内容：\r\n {0}", xmlContent));
                    /*
                     * 目前有两种回单样式
                    <Reply><Property Name="Description">与另外的提供商[code=9002]存在重复编码</Property><Property Name="Result">-1</Property></Reply>

                    <Reply><Result>9406</Result><Description>cdna0000000000000000000000000001: -- -1:失败[通知文件中未找到错误信息];;;</Description></Reply>
                    */
                    //使用XML模式读取回单数据
                    //XmlTextReader aa = new XmlTextReader(xmlContent.TrimStart(' '), new UTF8Encoding(false));

                    XDocument rootNode = XDocument.Parse(xmlContent.TrimStart(' '));
                    var movieNodes = from myTarget in rootNode.Descendants("Property")
                                     where myTarget.Attribute("Name").Value.Equals("Result")
                                     select myTarget;
                    if (movieNodes.Any())
                    {
                        Console.WriteLine("提取到{0}条回执信息", movieNodes.Count());
                        foreach (var item in movieNodes)
                        {
                            //Console.WriteLine(item.Attribute("Name").Value);
                            //Console.WriteLine(item.Value);
                            if (item.Value.Equals("-1"))
                            {
                                Console.WriteLine(item.Value);
                                XNode a = item.NextNode;  //获取同级的下一节点数据
                                Console.WriteLine(((XElement)a).Value);
                                sbContent.Append(string.Format("ErrCode:{0} Message:{1} ", item.Value, ((XElement)a).Value));
                            }

                        }
                    }
                    else
                    {
                        //LogHelper.WriteErrorLogEx(logName, "未找到回执错误消息");
                    }

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            
            return sbContent.ToString();
        }

        public string ReadXmlElement(string xmlPath)
        {
            try
            {
                if (File.Exists(xmlPath))
                {
                    XElement doc = XElement.Load(xmlPath);
                    var tt = doc.Descendants();
                    IEnumerable<XElement> childList = from el in doc.Elements() select el;
                    foreach (XElement e in childList)
                        Console.WriteLine(e);
                }
                return string.Empty;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                throw;
            }
        }

        public string ReadXmlNode(string xmlPath)
        {
            try
            {
                if (File.Exists(xmlPath))
                {
                    XDocument rootNode = XDocument.Load(xmlPath);
                    XElement rootElement = rootNode.Root;
                    //Console.WriteLine(rootNode.Document.ToString());
                    var nodes = rootNode.DescendantNodes();
                    var abc = rootElement.Descendants("{http://smc.huawei.com/}LoginRequestResponse").FirstOrDefault();
                    if (abc.Nodes().Count() > 0)
                    {
                        Console.WriteLine(abc.Value);
                        foreach (var item in abc.Nodes())
                        {
                            Console.WriteLine(item.NodeType);
                            //if (item.)
                            //{

                            //}
                            Console.WriteLine(item);
                        }
                    }
                    //搜索的时候要加上Namespace值，比如XMLNS如果写了<LoginRequestResponse xmlns="http://smc.huawei.com/">，则此节点及它的子节点都需要加上这个才能检索到
                    var runNodes = from target in rootNode.Root.Descendants("{http://smc.huawei.com/}LoginRequestResponse") select target;
                    if (runNodes.Any())
                    {
                        foreach (var item in runNodes)
                        {
                            Console.WriteLine(item.NodeType);
                            Console.WriteLine(item.Name);
                            if (item.HasElements)
                            {
                                foreach (var itemE in item.Elements())
                                {
                                    if (itemE.IsEmpty)
                                    {
                                        Console.WriteLine(itemE.Value);
                                    }
                                    Console.WriteLine(itemE.Name.LocalName);
                                    Console.WriteLine(itemE.Value);
                                }
                            }
                            else
                            {
                                Console.WriteLine(item.Value);
                            }
                            
                        }
                    }
                    
                    foreach (var item in rootElement.Elements())
                    {
                        var subnodes = item.DescendantNodes();
                        if (subnodes.Any())
                        {
                            foreach (var itemN in subnodes)
                            {
                                Console.WriteLine(item.NodeType);
                                Console.WriteLine(item.Name);
                            }
                        }
                        foreach (var itemNode in item.Nodes())
                        {
                            Console.WriteLine(itemNode.ToString());
                        }
                        if (item.HasElements)
                        {
                            var tt = item.Element("randomSequence");
                            if (item.Elements().Count() > 0)
                            {

                            }
                            foreach (var subitem in item.Elements())
                            {
                                Console.WriteLine(subitem.Name);
                                Console.WriteLine(subitem.Value);
                            }
                        }
                        LogHelper.WriteInfoLog(item.Name.ToString());
                    }

                    var tmpEls = rootNode.Elements("{http://smc.huawei.com/}LoginRequestResponse");
                    if (tmpEls.Any())
                    {
                        var aa = tmpEls.Nodes();
                        //List<string> nodesTxt = GetContentNode(rootElement);
                        //if (nodesTxt.Count > 0)
                        //{

                        //}
                        var movieNodes = from myTarget in rootNode.Descendants("Property")
                                         where myTarget.Attribute("Name").Value.Equals("Result")
                                         select myTarget;
                        if (movieNodes.Any())
                        {
                            foreach (var item in movieNodes)
                            {
                                //Console.WriteLine(item.Attribute("Name").Value);
                                //Console.WriteLine(item.Value);
                                if (item.Value.Equals("-1"))
                                {
                                    Console.WriteLine(item.Value);
                                    XNode a = item.NextNode;  //获取同级的下一节点数据
                                    Console.WriteLine(((XElement)a).Value);
                                }

                            }
                        }

                    }
                }
                return "";
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorLog(ex.ToString());
                return "";
            }
        }

        /// <summary>
        /// XML数据获取并转指定对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xmlPath"></param>
        /// <param name="xmlns"></param>
        /// <param name="filed"></param>
        /// <returns></returns>
        public T ReadXmlObjects<T>(string xmlPath, string xmlns, string filed) where T:class, new()
        {
            if (File.Exists(xmlPath))
            {
                string xPath = string.Empty;
                string mask = string.Empty;
                XDocument doc = XDocument.Load(xmlPath);
                if (string.IsNullOrEmpty(xmlns))
                {
                    xPath = filed;
                }
                else
                {
                    xPath = string.Format("{{{0}}}{1}", xmlns, filed);
                    mask = string.Format(" xmlns=\"{0}\"", xmlns);
                }
                var xNode = doc.Root.Descendants(xPath).FirstOrDefault();
                if (xNode != null)
                {
                    //string tmpXml = xNode.ToString().Replace(mask, "");
                    string tmpXml = xNode.ToString();
                    return DeSerialize<T>(tmpXml);
                }
            }

            return default(T);
        }

        private List<string> GetContentNode(XElement rootElement)
        {
            List<string> nodesTxt = new List<string>();
            foreach (XElement item in rootElement.Elements())
            {
                if (item.HasElements)
                {
                    nodesTxt.AddRange(GetContentNode(item));
                }
                else
                {
                    Console.WriteLine(item.Attribute("Name").Value);
                    if (item.Attribute("Name").Value.Equals("Result"))
                    {
                        Console.WriteLine(item.Value);
                        XNode tmp = item.NextNode;
                        string abc = tmp.ToString();
                        XDocument tmpDoc = tmp.Document;
                    }
                    nodesTxt.Add(item.Value);
                    //foreach (var itema in item.Elements())
                    //{
                        
                    //}
                }
            }
            return nodesTxt;
        }

        /// <summary>  
        /// 反序列化xml字符为对象，默认为Utf-8编码  
        /// </summary>  
        /// <typeparam name="T"></typeparam>  
        /// <param name="xml"></param>  
        /// <returns></returns>  
        public T DeSerialize<T>(string xml) where T : class, new()
        {
            return DeSerialize<T>(xml, Encoding.UTF8);
        }

        /// <summary>  
        /// 反序列化xml字符为对象  
        /// </summary>  
        /// <typeparam name="T"></typeparam>  
        /// <param name="xml"></param>  
        /// <param name="encoding"></param>  
        /// <returns></returns>  
        public T DeSerialize<T>(string xml, Encoding encoding) where T : new()
        {
            try
            {
                var mySerializer = new XmlSerializer(typeof(T));
                using (var ms = new MemoryStream(encoding.GetBytes(xml)))
                {
                    using (var sr = new StreamReader(ms, encoding))
                    {
                        return (T)mySerializer.Deserialize(sr);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return default(T);
            }

        }
    }
}
